<?php
/**
 * +----------------------------------------------------------------------+
 * php23种设计模式实现-合成模式
 * Author：微信公众号：yuantanphp
 * 获取更多资源，技术答疑，项目合作请关注微信公众号：yuantanphp
 * +----------------------------------------------------------------------+
 */
/**
 * 组合模式抽象基类
 */
abstract class CompanyBase{
    //节点名称
    protected $name;

    public function __construct($name){

        $this->name = $name;
    }

    public function getName(){
        return $this->name;
    }

    //增加节点
    abstract function add(CompanyBase $c);

    //删除节点
    abstract function remove(CompanyBase $c);

    //输出节点信息
    abstract function show($deep);

    //节点职责
    abstract function work($deep);

}

/**
 * 公司类
 */
class Company extends CompanyBase{
    protected $item = [];

    public function add(CompanyBase $c){
        $nodeName = $c->getName();

        if(!isset( $this->item[$nodeName] )){

            $this->item[$nodeName] = $c;
        }else{
            throw new Exception("该节点已存在,节点名称：".$nodeName);
        }
    }

    public function remove(CompanyBase $c){
        $nodeName = $c->getName();

        if(isset( $this->item[$nodeName] )){

            unset($this->item[$nodeName]);
        }else{
            throw new Exception("该节点不存在,节点名称：".$nodeName);
        }
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

        foreach($this->item as $value){
            $value->show($deep+4);
        }

    }
    public function work($deep = 0){

        foreach($this->item as $value){
            echo str_repeat(" ",$deep)."[{$this->name}]<br>";
            $value->work($deep+2);
        }
    }

}

/**
 * 行政部门
 */
class Administrative extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("该节点下不能增加节点");
    }

    public function remove(CompanyBase $c){

        throw new Exception("该节点下无子节点");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat(" ",$deep)."行政部门主要负责公司文书以及附带人力资源及相关培训";
        echo "<br>";
    }

}

/**
 * 财务部门
 */
class Financial extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("该节点下不能增加节点");
    }

    public function remove(CompanyBase $c){

        throw new Exception("该节点下无子节点");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat(" ",$deep)."财务部门主要负责公司财务";
        echo "<br>";
    }
}
/**
 * 生产部门
 */
class Production extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("该节点下不能增加节点");
    }

    public function remove(CompanyBase $c){

        throw new Exception("该节点下无子节点");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat(" ",$deep)."生产部门主要负责生产组装摩托";
        echo "<br>";
    }
}
/**
 * 售后部门
 */
class AfterSales extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("该节点下不能增加节点");
    }

    public function remove(CompanyBase $c){

        throw new Exception("该节点下无子节点");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat(" ",$deep)."售后部门主要负责公司产品售后咨询对接";
        echo "<br>";
    }
}
/**
 * 后勤部门
 */
class Logistics extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("该节点下不能增加节点");
    }

    public function remove(CompanyBase $c){

        throw new Exception("该节点下无子节点");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat(" ",$deep)."后勤部门为公司提供后勤服务";
        echo "<br>";
    }
}
$administrative = new Administrative("行政部门");
$financial = new Financial("财务部门");
$production = new Production("生产部门");
$logistics = new Logistics("后勤部门");
$afterSales = new AfterSales("售后部门");

//北京摩托公司
$companyBj = new Company("北京摩托公司");

$companyBj->add($administrative);
$companyBj->add($financial);
$companyBj->add($afterSales);

//广西摩托分公司
$companyGx = new Company("广西摩托分公司");
$companyGx->add($administrative);
$companyGx->add($financial);
$companyGx->add($production);
$companyGx->add($logistics);
$companyBj->add($companyGx);

//广东摩托分公司
$companyGd = new Company("广东摩托分公司");
$companyGd->add($administrative);
$companyGd->add($financial);
$companyGd->add($production);
$companyGd->add($logistics);
$companyBj->add($companyGd);

//使用公司功能
$companyBj->show();
$companyBj->work();